package com.ohs.bll.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ohs.bll.service.AccountService;
import com.ohs.bll.service.MailService;
import com.ohs.bll.util.ConfigurationManager;
import com.ohs.bll.util.Constant;
import com.ohs.bll.util.PasswordUtil;
import com.ohs.bo.form.LoginUser;
import com.ohs.dal.dao.AccountDAO;
import com.ohs.dal.dao.LocationDAO;
import com.ohs.dal.dao.RoleDAO;
import com.ohs.dal.model.Account;
import com.ohs.dal.model.Location;
import com.ohs.dal.model.Province;
import com.ohs.dal.model.Role;
import com.ohs.dal.model.Specialty;

public class AccountServiceImpl implements AccountService {

	private Log log = LogFactory.getLog(AccountServiceImpl.class);
	
	AccountDAO accountDAO;

	RoleDAO roleDAO;
	
	LocationDAO locationDAO;
	
	MailService mailService;
	
	// DI via Spring
	public void setCustomerDAO(AccountDAO accountDAO) {
		this.accountDAO = accountDAO;
	}

	// call DAO to return customers
	public List<Account> list() {
		return accountDAO.list();
	}

	public AccountDAO getAccountDAO() {
		return accountDAO;
	}

	public void setAccountDAO(AccountDAO accountDAO) {
		this.accountDAO = accountDAO;
	}

	public LoginUser checkLogin(String username, String password) {
		Account account = accountDAO.get(username);
		try {
			if (account != null && account.getPassword().equals(PasswordUtil.encrypt(password))) {
				LoginUser user = new LoginUser(username, account.getStep());
				return user;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public boolean update(String username, String password, String name, String age,
			String title, long roleId, boolean addNew) {
		Account account = accountDAO.get(username);
		Role role = roleDAO.get(roleId);
		if (!addNew) {
			account.setName(name);
			account.setPassword(password);
			if (age != null && !"".equals(age)) {
				account.setAge(Integer.parseInt(age));
			}
			account.setRole(role);
			account.setUpdateDate(new Date());
			accountDAO.update(account);
			return true;
		} else {
			if (account != null) {
				return false;
			} else {
				account = new Account();
				account.setUsername(username);
				account.setName(name);
				account.setPassword(password);
				if (age != null && !"".equals(age)) {
					account.setAge(Integer.parseInt(age));
				}
				account.setRole(role);
				account.setCreatedDate(new Date());
				accountDAO.update(account);
				return true;
			}
		}
	}

	public void delete(String username) {
		Account account = accountDAO.get(username);
		if (account != null) {
			accountDAO.delete(account);
		}
	}

	public Account get(String username) {
		return accountDAO.get(username);
	}
	
	public boolean forgotPass(String info) throws Exception {
		Account account = accountDAO.get(info);
		if (account == null) {
			account = accountDAO.getByEmail(info);
		}
		if (account != null) {
			String newPass = RandomStringUtils.randomAlphanumeric(6);
			try {
				String domain = ConfigurationManager.getAsString(ConfigurationManager.CONFIG, "sitedomain");
				String msg = "";
				msg += "\r\nTên đăng nhập của bạn là: " + account.getUsername();
				msg += "\r\nMật khẩu mới của bạn là: " + newPass;
				msg += "\r\nVui lòng sử dụng mật khẩu mới này để đăng nhập vào " + domain + "/home/login và thay đổi mật khẩu";
				msg += "\r\n\r\n Xin cảm ơn,";
				mailService.sendMail(account.getEmail(), "Cung cấp lại mật khẩu tại " + domain, msg);
				
				account.setPassword(PasswordUtil.encrypt(newPass));
				accountDAO.update(account);
				return true;
			} catch (Exception e) {
				log.error("Failed to send forgot password email to: "  + account.getEmail());
			}
		}
		return false;
	}

	public RoleDAO getRoleDAO() {
		return roleDAO;
	}

	public void setRoleDAO(RoleDAO roleDAO) {
		this.roleDAO = roleDAO;
	}

	public boolean createDoctor(Account account, String address, String name, long provinceId) {
		Account anAccount = accountDAO.get(account.getUsername());
		if (anAccount != null) {
			return false;
		}
		Role role = roleDAO.getByName(Constant.ROLE_DOCTOR);
		account.setRole(role);
		accountDAO.add(account);
		
		// add default location
		Location location = new Location();
		location.setCreatedDate(new Date());
		location.setAccount(account);
		location.setAddress(address);
		location.setName(name);
		location.setAllowBookBefore(1);
		location.setAllowBookRightaway(true);
		location.setComeBefore(10);
		location.setRating(0);
		Province province = locationDAO.getProvince(provinceId);
		location.setProvince(province);
		locationDAO.add(location);
		
		//send mail
		try {
			String msg = "Chúc mừng bạn đã đăng kí thành công tại website: " + ConfigurationManager.getAsString(ConfigurationManager.CONFIG, "sitedomain");
			msg += "\r\nTên đăng nhập của bạn là: " + account.getUsername();
			msg += "\r\nVui lòng đăng nhập vào website để hoàn tất đăng kí thông tin phòng khám";
			msg += "\r\nMọi thắc mắc xin vui lòng liên hệ: dathenkhambenh.com@gmail.com";
			msg += "\r\n\r\n Xin cảm ơn,";
			mailService.sendMail(account.getEmail(), "Chúc mừng bạn đã đăng kí thành công", msg);
		} catch (Exception e) {
			log.error("Failed to send mail to: "  + account.getEmail());
		}
		return true;
	}
	
	public boolean updateDoctor(Account account, Location location, long provinceId, long[] specialtyArr) {
		// update default location
		Location locationObj = locationDAO.getByAccount(account.getUsername());
		locationObj.setUpdateDate(new Date());
		locationObj.setAccount(account);
		locationObj.setAddress(location.getAddress());
		locationObj.setName(location.getName());
		locationObj.setInfo(location.getInfo());
		locationObj.setImageUrl(location.getImageUrl());
		if (location.getLatitudes() != null && !"".equals(location.getLatitudes())) {
			locationObj.setLatitudes(location.getLatitudes());
		}
		if (location.getLongitudes() != null && !"".equals(location.getLongitudes())) {
			locationObj.setLongitudes(location.getLongitudes());
		}
		Province province = locationDAO.getProvince(provinceId);
		locationObj.setProvince(province);
		
		Specialty spec = null;
		if (specialtyArr[0] > 0) {
			spec = accountDAO.getSpecialty(specialtyArr[0]);
			locationObj.setSpecialty1(spec);
		} else {
			locationObj.setSpecialty1(null);
		}
		if (specialtyArr[1] > 0) {
			spec = accountDAO.getSpecialty(specialtyArr[1]);
			locationObj.setSpecialty2(spec);
		} else {
			locationObj.setSpecialty2(null);
		}
		if (specialtyArr[2] > 0) {
			spec = accountDAO.getSpecialty(specialtyArr[2]);
			locationObj.setSpecialty3(spec);
		} else {
			locationObj.setSpecialty3(null);
		}
		if (specialtyArr[3] > 0) {
			spec = accountDAO.getSpecialty(specialtyArr[3]);
			locationObj.setSpecialty4(spec);
		} else {
			locationObj.setSpecialty4(null);
		}
		if (specialtyArr[4] > 0) {
			spec = accountDAO.getSpecialty(specialtyArr[4]);
			locationObj.setSpecialty5(spec);
		} else {
			locationObj.setSpecialty5(null);
		}
		locationDAO.update(locationObj);
		return true;
	}

	public LocationDAO getLocationDAO() {
		return locationDAO;
	}

	public void setLocationDAO(LocationDAO locationDAO) {
		this.locationDAO = locationDAO;
	}

	public boolean update(Account account) {
		accountDAO.update(account);
		return false;
	}

	public MailService getMailService() {
		return mailService;
	}

	public void setMailService(MailService mailService) {
		this.mailService = mailService;
	}

	public List<Specialty> getAllSpecialty() {
		return accountDAO.getAllSpecialty();
	}

}